﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;

namespace SoftSource.Common
{
    public static class EnumerationExtensions
    {
        public static bool TryGetDisplayName<T>(this T enumValue, out string displayName)
        {
            Type enumType = enumValue.GetType();

            if (!enumType.IsEnum)
            {
                throw new ArgumentException("Type " + enumType.Name + " is not an enum");
            }

            return TryGetDisplayName(enumType, enumValue, out displayName);
        }

        public static bool TryGetDisplayName<T>(this Type enumType, T enumValue, out string displayName)
        {
            if (!enumType.IsEnum)
            {
                throw new ArgumentException("Type " + enumType.Name + " is not an enum");
            }

            var values = enumType.GetKeyValues();

            if (values.ContainsKey(enumValue))
            {
                displayName = values[enumValue];
                return true;
            }
            else
            {
                displayName = string.Empty;
                return false;
            }
        }

        public static Dictionary<object, string> GetKeyValues(this Type enumType)
        {
            if (!enumType.IsEnum)
            {
                throw new ArgumentException("Type " + enumType.Name + " is not an enum");
            }

            Dictionary<object, string> values = new Dictionary<object, string>();

            var fields = enumType.GetLiteralFields();

            foreach (FieldInfo field in fields)
            {
                object key = field.GetValue(enumType);
                string displayName = field.GetDisplayName(key.ToString());

                values.Add(key, displayName);
            }
            return values;
        }

        public static IEnumerable GetValues(this Type enumType)
        {
            if (!enumType.IsEnum)
            {
                throw new ArgumentException("Type " + enumType.Name + " is not an enum");
            }

            List<object> values = new List<object>();

            var fields = enumType.GetLiteralFields();

            foreach (FieldInfo field in fields)
            {
                object value = field.GetValue(enumType);
                values.Add(value);
            }

            return values;
        }

        public static IEnumerable<T> GetValues<T>()
        {
            Type enumType = typeof(T);
            return GetValues(enumType) as IEnumerable<T>;
        }
    }
}
